package com.spi.soconversion.jmsqueue;

import java.io.File;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

import com.spi.soconversion.base.SOCException;
import com.spi.soconversion.util.ConversionType;
import com.spi.soconversion.util.ErrorConstants;
import com.spi.soconversion.util.ErrorMessageReader;
import com.spi.soconversion.util.QueryConstants;
import com.spi.soconversion.util.QueryReader;
import com.spi.soconversion.util.ResourceProvider;
import com.spi.soconversion.util.SOCConstants;
import com.spi.soconversion.util.SOCFileWriter;
import com.spi.soconversion.util.SOCUtility;

public class JMSInitializer {

	static private org.apache.commons.logging.Log log = 
	    org.apache.commons.logging.LogFactory.getLog(JMSInitializer.class);
	
	private Timestamp startTime;
	private SOCFileWriter d_FileWriter;
	private List<String> listedDir= new ArrayList<String>();
	private String d_conversionType;
	private Timestamp endTime;
	private String d_xmlDirectory;
	private int d_batchNum;
	private String d_logFileName;		
	
	public JMSInitializer(String d_xmlDirectory, int d_batchNum, String d_logFileName, SOCFileWriter d_FileWriter , String d_conversionType)
	{
		this.d_xmlDirectory= d_xmlDirectory;
		this.d_batchNum=d_batchNum;
		this.d_logFileName= d_logFileName;
		this.d_FileWriter= d_FileWriter;
		this.d_conversionType= d_conversionType;
	}
	public void getDirectoriesForJMSQueue() throws SOCException
	{
		startTime = new Timestamp(System.currentTimeMillis());
		//d_xmlDirectory=d_xmlDirectory+SOCConstants.DELIMITER+SOCConstants.BATCH+SOCConstants.UNDERSCORE+d_batchNum;
		File XMLDirRef= new File(d_xmlDirectory);
		if (!XMLDirRef.exists())
		{
			d_FileWriter = new SOCFileWriter();
			d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(ErrorMessageReader.getError(
					ErrorConstants.BATCH_NOT_EXIST)+d_batchNum));
			throw new SOCException(
					ErrorMessageReader.getError(
							ErrorConstants.BATCH_NOT_EXIST)+d_batchNum);
		}
		d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(SOCConstants.JMS_QUEUE_GET_DIR_NAMES_START_PROCESSING+d_xmlDirectory));
		
		File[] subDir=XMLDirRef.listFiles();
		
		if(subDir!=null)

		{
			for(File file : subDir)
			{
				if(file.isDirectory())
				{
					String absolutePath = file.getAbsolutePath();
					// XSD validation not happening for closed sales or open sales so there willn't be any good records directory
					if(d_conversionType.equals(ConversionType.INSTALLBASE.getDisplayText())) {
						absolutePath=absolutePath+SOCConstants.DELIMITER+SOCConstants.DIR_NAME_GOOD_RECORDS;
					}

					listedDir.add(absolutePath);
				}
			}
		}
		
		d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(SOCConstants.JMS_QUEUE_GET_DIR_NAMES_END_PROCESSING+d_xmlDirectory));
	}
    
    public void sendFileToJMSQueue() throws SOCException
	{
    	log.info("Sending the xml files to JMS Queue...");
		if(listedDir!=null && listedDir.size()>0)
		{
			
			d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(SOCConstants.JMS_QUEUE_START_PROCESSING));
			JMSQueue jmsQueueHandler = new JMSQueue(d_conversionType,d_logFileName,d_FileWriter);
			jmsQueueHandler.getJMSClient();
			List<SOCListableThread<JMSQueueProcessor>> threads = new ArrayList<SOCListableThread<JMSQueueProcessor>>();
			for(String dirName: listedDir)
			{
				SOCListableThread<JMSQueueProcessor> thread = new SOCListableThread<JMSQueueProcessor>(new JMSQueueProcessor(jmsQueueHandler,dirName,d_logFileName,d_FileWriter));

				threads.add(thread);
				thread.start();		
			}
			StringBuilder succesMsg = new StringBuilder();
			StringBuilder failureMsg = new StringBuilder();
			for (SOCListableThread<JMSQueueProcessor> thread : threads) {
				try {
					boolean result = thread.get();
					if(result) {
						if(succesMsg.length()>0) {
							succesMsg.append(SOCConstants.COMMA+thread.getDirName());							
						}
						else {
							succesMsg.append(thread.getDirName());	
						}
					}
					else {
						if(failureMsg.length()>0) {
							failureMsg.append(SOCConstants.COMMA+thread.getDirName());							
						}
						else {
							failureMsg.append(thread.getDirName());	
						}
						d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(ErrorMessageReader.getError(
								ErrorConstants.JMS_PUSH_FAIL_FOR_DIR)+thread.getDirName()));					
					}
				} catch (ExecutionException e) {
					e.printStackTrace();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				endTime = new Timestamp(System.currentTimeMillis());
				updateJMSQueueInfo(succesMsg.toString(), failureMsg.toString());
				
			}
			d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(SOCConstants.JMS_QUEUE_END_PROCESSING));
		}
		else
		{
			d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(SOCConstants.NO_XML_SUB_DIRS_FOR_JMS_QUEUE+d_xmlDirectory));
		}
		
	}
    
    public void updateJMSQueueInfo(String successMsg, String failureMsg) throws SOCException
    {
    	String batchUpdateQuery = QueryReader.getQuery(QueryConstants.INSERT_CONVERSION_JMS_STATISTICS_QUERY);
    	PreparedStatement batchStmt=null;
    	int recordCount=0;
    	try {
    		ResourceProvider provider = ResourceProvider.getInstance();
    		batchStmt=provider.getdbConnection().prepareStatement(batchUpdateQuery);
    		batchStmt.setString(1, d_conversionType);
    		batchStmt.setInt(2, d_batchNum);
    		batchStmt.setTimestamp(3,startTime);
    		batchStmt.setTimestamp(4, endTime);    		
    		batchStmt.setString(5, successMsg);
    		batchStmt.setString(6, failureMsg);
    		    		
    		recordCount=batchStmt.executeUpdate();
    		if(recordCount==0)
			{
				d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(ErrorMessageReader.getError(
	            				ErrorConstants.NO_RECORD_POPULATION_TBL_JMS_QUEUE_STATISTICS)));
				throw new SOCException(
	            		ErrorMessageReader.getError(
	            				ErrorConstants.NO_RECORD_POPULATION_TBL_JMS_QUEUE_STATISTICS));
			}	
		}
		catch(SQLException sqle)
		{
			d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(ErrorMessageReader.getError(
    				ErrorConstants.FAILED_UPDATE_JMS_STATISTICS_INFO)+SOCConstants.NEW_LINE+sqle.getMessage()));
			throw new SOCException(
            		ErrorMessageReader.getError(
            				ErrorConstants.FAILED_UPDATE_JMS_STATISTICS_INFO) ,sqle);
    		
		}	
    }	
}
